package com.easyadmin.service.impl;

import com.easyadmin.entity.enums.PageSize;
import com.easyadmin.entity.po.SysDict;
import com.easyadmin.entity.query.SysDictQuery;
import com.easyadmin.entity.vo.PaginationResult;
import com.easyadmin.entity.vo.SimplePage;
import com.easyadmin.exception.BusinessException;
import com.easyadmin.mappers.SysDictMapper;
import com.easyadmin.service.SysDictService;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;


/**
 * 业务接口实现
 */
@Service("sysDictService")
public class SysDictServiceImpl implements SysDictService {

    @Resource
    private SysDictMapper<SysDict, SysDictQuery> sysDictMapper;

    /**
     * 根据条件查询列表
     */
    @Override
    public List<SysDict> findListByParam(SysDictQuery param) {
        return this.sysDictMapper.selectList(param);
    }

    /**
     * 根据条件查询列表
     */
    @Override
    public Integer findCountByParam(SysDictQuery param) {
        return this.sysDictMapper.selectCount(param);
    }

    /**
     * 分页查询方法
     */
    @Override
    public PaginationResult<SysDict> findListByPage(SysDictQuery param) {
        int count = this.sysDictMapper.selectCount(param);
        int pageSize = param.getPageSize() == null ? PageSize.SIZE15.getSize() : param.getPageSize();
        int pageNo = 0;
        if (null != param.getPageNo()) {
            pageNo = param.getPageNo();
        }
        SimplePage page = new SimplePage(pageNo, count, pageSize);
        param.setSimplePage(page);
        List<SysDict> list = this.sysDictMapper.selectList(param);
        if (param.getQueryChildren() != null && param.getQueryChildren()) {
            for (SysDict sysDict : list) {
                SysDictQuery subQuery = new SysDictQuery();
                subQuery.setPid(sysDict.getId());
                subQuery.setOrderBy("sort asc");
                sysDict.setSubData(this.sysDictMapper.selectList(subQuery));
            }
        }
        PaginationResult<SysDict> result = new PaginationResult<>(count, pageSize, pageNo, page.getPageTotal(), list);
        return result;
    }

    /**
     * 新增
     */
    @Override
    public Integer add(SysDict bean) throws BusinessException {
        try {
            return this.sysDictMapper.insert(bean);
        } catch (DuplicateKeyException e) {
            throw new BusinessException("信息已经存在");
        }
    }

    /**
     * 批量新增
     */
    @Override
    public Integer addBatch(List<SysDict> listBean) {
        if (listBean == null || listBean.isEmpty()) {
            return 0;
        }
        return this.sysDictMapper.insertBatch(listBean);
    }

    /**
     * 批量新增或者修改
     */
    @Override
    public Integer addOrUpdateBatch(List<SysDict> listBean) {
        if (listBean == null || listBean.isEmpty()) {
            return 0;
        }
        return this.sysDictMapper.insertOrUpdateBatch(listBean);
    }

    /**
     * 根据PropValueAndPid修改
     */
    @Override
    public Integer updateByPropValueAndPid(SysDict bean, String propValue, Integer pid) {
        return this.sysDictMapper.updateByPropValueAndPid(bean, propValue, pid);
    }


    /**
     * 根据PropValueAndPid删除
     */
    @Override
    public Integer deleteByPropValueAndPid(String propValue, Integer pid) {
        return this.sysDictMapper.deleteByPropValueAndPid(propValue, pid);
    }


    /**
     * 根据PropValueAndPid获取对象
     */
    @Override
    public SysDict getSysDictByPropValueAndPid(String propValue, Integer pid) {
        return this.sysDictMapper.selectByPropValueAndPid(propValue, pid);
    }


    /**
     * 根据Id修改
     */
    @Override
    public Integer updateById(SysDict bean, Integer id) {
        return this.sysDictMapper.updateById(bean, id);
    }


    /**
     * 根据Id删除
     */
    @Override
    public Integer deleteById(Integer id) {
        return this.sysDictMapper.deleteById(id);
    }


    /**
     * 根据Id获取对象
     */
    @Override
    public SysDict getSysDictById(Integer id) {
        return this.sysDictMapper.selectById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveDict(SysDict sysDict) throws BusinessException {
        SysDict dbData = this.sysDictMapper.selectByPropValueAndPid(sysDict.getPropValue(), sysDict.getPid());

        if (sysDict.getId() == null && dbData != null || sysDict.getId() != null && dbData != null && !sysDict.getId().equals(dbData.getId())) {
            throw new BusinessException("属性值【" + sysDict.getPropValue() + "】已经存在");
        }

        if (sysDict.getId() == null) {
            this.sysDictMapper.insert(sysDict);
        } else {
            this.sysDictMapper.updateById(sysDict, sysDict.getId());
        }
        List<SysDict> children = sysDict.getSubData();
        if (sysDict.getId() != null) {
            SysDictQuery dictQuery = new SysDictQuery();
            dictQuery.setPid(sysDict.getId());
            List<SysDict> dbChildren = this.sysDictMapper.selectList(dictQuery);
            for (SysDict item : dbChildren) {
                Boolean haveDel = true;
                for (SysDict p : children) {
                    if (p.getId() != null && p.getId().equals(item.getId())) {
                        haveDel = false;
                        break;
                    }
                }
                if (haveDel) {
                    this.sysDictMapper.deleteById(item.getId());
                }
            }
        }
        for (int i = 0; i < children.size(); i++) {
            SysDict sub = children.get(i);
            sub.setSort(i);
            sub.setPid(sysDict.getId());
            SysDict subDb = this.sysDictMapper.selectByPropValueAndPid(sub.getPropValue(), sysDict.getId());

            if (sub.getId() == null) {
                if (subDb != null) {
                    throw new BusinessException("第【" + (i + 1) + "】行属性值已经存在");
                }
                this.sysDictMapper.insert(sub);
            } else {
                if (subDb != null && !subDb.getId().equals(sub.getId())) {
                    throw new BusinessException("第【" + (i + 1) + "】行属性值已经存在");
                }
                this.sysDictMapper.updateById(sub, sub.getId());
            }
        }
    }
}